#include "filtros.h"
#include "fstream"
#include <iostream>
#include "string.h"

using namespace std;

filtros::filtros() //Constructor.. por ahora vacio
{
}

void filtros::fijarKernel(int a,int b) //fijar las dimensiones del kernel 
									   //(por ejemplo fijarKernel(3,3) para aplicar kernel 3x3)
{
    kernel.push_back(a);
    kernel.push_back(b);
}

vector <int> filtros::obtenerKernel() //retorna un vector con las 2 dimensiones del kernel
{
    return kernel;
}
void filtros::fijarParametroExtra(int n,int a)
//fijar un parametro extra
//n es la posicion en el vector de parametros donde se va a guardar
//a es el valor del parametro
												
{
    if(n<nParametrosExtra)
    {
        parametroExtra.at(n)=a;
    }

}

int  filtros::obtenerParametroExtra(int n)
{
// retorna el parametro extra guardado en la posicion n del vector de parametros

    if(n<nParametrosExtra)
    {
        return parametroExtra.at(n);
    }
    else
        return 0;
}

string filtros::obtenerNombre()
{
// retorna el nombre del filtro
    return nombre;
}

vector <int> filtros::obtenerParametrosExtra()
{
//retorna el vector que contiene todos los parametros extra
    return parametroExtra;
}

int filtros::obtenerNParametrosExtra()
{
//este metodo retorna el numero de parametros extra que posee el filtro
    return nParametrosExtra;
}

/////////////////////////////Filtro Mediana///////////////////////////////////

filtroMediana::filtroMediana()
{
    ifstream in("Filtros/datosFiltros.in");
    string aux;
    int aux1,aux2,aux3;
    vector<int> cola;
    bool bandera=false;
    int temp;
    vector<int>::iterator it;
    vector<int>::iterator it2;



    if(!in) {
        cout << " No es posible abrir fichero datosFiltro.in\n ";
    }

    while((in.eof()==false)||(bandera=false))
    {
        in >> aux >> aux1 >> aux2>> aux3;


        int n=aux3;

        for(int i=0;i<n;i++)
        {
            in >> temp;
            cola.push_back(temp);

        }
        if(aux=="Mediana")
        {
            nombre.assign(aux);
            kernel.push_back(aux1);
            kernel.push_back(aux2);
            nParametrosExtra=aux3;

            it = parametroExtra.begin();
            it2=cola.end();
            parametroExtra.insert(it,it2-nParametrosExtra,it2);

            bandera=true;

        }
    }
    in.close();
}

void filtroMediana::filtrar(IplImage  *img)
{
	//funcion de  OpenCV que aplica un filtro de mediana 
	//se usa de esta manera:
	//cvSmooth(imagen fuente,imagen destino, tipo de filtro, a,b)
	//a y b son las dimensiones del kernel
    cvSmooth(img,img,CV_MEDIAN,kernel[0],kernel[1]);
}

/////////////////////////////////Filtro gaussiano////////////////////////////////////////////////

filtroGauss::filtroGauss()
{
	//en el contructor cargamos los datos del filtro del archivo datosFiltros.in
    ifstream in("Filtros/datosFiltros.in");
    string aux;
    int aux1,aux2,aux3;
    vector<int> cola;
    bool bandera=false;
    int temp;
    vector<int>::iterator it;
    vector<int>::iterator it2;



    if(!in) {
        cout << " No es posible abrir fichero datosFiltro.in\n ";
    }

    while((in.eof()==false)||(bandera=false))
    {
        in >> aux >> aux1 >> aux2>> aux3;


        int n=aux3;

        for(int i=0;i<n;i++)
        {
            in >> temp;
            cola.push_back(temp);

        }
        if(aux=="Gauss")
        {
            nombre.assign(aux);
            kernel.push_back(aux1);
            kernel.push_back(aux2);
            nParametrosExtra=aux3;
            it = parametroExtra.begin();
            it2=cola.end();
            parametroExtra.insert(it,it2-nParametrosExtra,it2);

            bandera=true;

        }
    }
    in.close();

}

void filtroGauss::filtrar(IplImage  *img)
{
	//funcion de  OpenCV que aplica un filtro gaussiano 
	//se usa de esta manera:
	//cvSmooth(imagen fuente,imagen destino, tipo de filtro, a,b)
	//a y b son las dimensiones del kernel
    cvSmooth(img,img,CV_GAUSSIAN,kernel[0],kernel[1]);
}

///////////////////////////////////Filtro MEan shift//////////////////////////////////
filtroMeanShift::filtroMeanShift()
{
	//en el contructor cargamos los datos del filtro del archivo datosFiltros.in
    ifstream in("Filtros/datosFiltros.in");
    string aux;
    int aux1,aux2,aux3;
    vector<int> cola;
    bool bandera=false;
    int temp;
    vector<int>::iterator it;
    vector<int>::iterator it2;



    if(!in) {
        cout << " No es posible abrir fichero datosFiltro.in\n ";
    }

    while((in.eof()==false)||(bandera=false))
    {
        in >> aux >> aux1 >> aux2>> aux3;


        int n=aux3;

        for(int i=0;i<n;i++)
        {
            in >> temp;
            cola.push_back(temp);

        }
        if(aux=="MeanShift")
        {
            nombre.assign(aux);
            kernel.push_back(aux1);
            kernel.push_back(aux2);
            nParametrosExtra=aux3;
            it = parametroExtra.begin();
            it2=cola.end();
            parametroExtra.insert(it,it2-nParametrosExtra,it2);

            bandera=true;

        }
    }
    in.close();
}

void filtroMeanShift::filtrar(IplImage  *img)
{
    //cvPyrMeanShiftFiltering(img,img,parametroExtra[0],parametroExtra[1],1 );
}

/////////////////////////////////////////FIltro Bilateral/////////////////////////

filtroBilateral::filtroBilateral()
{
	//en el contructor cargamos los datos del filtro del archivo datosFiltros.in
    ifstream in("Filtros/datosFiltros.in");
    string aux;
    int aux1,aux2,aux3;
    vector<int> cola;
    bool bandera=false;
    int temp;
    vector<int>::iterator it;
    vector<int>::iterator it2;



    if(!in) {
        cout << " No es posible abrir fichero datosFiltro.in\n ";
    }

    while((in.eof()==false)||(bandera=false))
    {
        in >> aux >> aux1 >> aux2>> aux3;


        int n=aux3;

        for(int i=0;i<n;i++)
        {
            in >> temp;
            cola.push_back(temp);

        }
        if(aux=="Bilateral")
        {
            nombre.assign(aux);
            kernel.push_back(aux1);
            kernel.push_back(aux2);
            nParametrosExtra=aux3;
            it = parametroExtra.begin();
            it2=cola.end();
            parametroExtra.insert(it,it2-nParametrosExtra,it2);

            bandera=true;

        }
    }
    in.close();

}


void filtroBilateral::filtrar(IplImage  *img)
{
	//funcion de  OpenCV que aplica un filtro Bilateral
	//se usa de esta manera:
	//cvSmooth(imagen fuente,imagen destino, tipo de filtro, a,b,c,d)
	//a y b son las dimensiones del kernel (deben ser 0 sino da error)
	//c indica el dominio espacial
	//d indica el rango de colores que se va a tomar
    IplImage* img2 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 3 );
    img2 = cvCloneImage(img);
    cvSmooth(img2,img,CV_BILATERAL,kernel[0],kernel[1],parametroExtra[0],parametroExtra[1]);
    cvReleaseImage(&img2);
}

